/*--------------------------------------------------------------------------------*/
#ifndef __GRAPHIC_TEXT_CONTAINER__
#define __GRAPHIC_TEXT_CONTAINER__
/*--------------------------------------------------------------------------------*/
#include "primitives.h"
#include "object.h"
#include "util.h"
#include "graphic_font.h"
#include "array.h"
#include "graphic_vertex_buffer.h"
#include "color.h"
#include "math_vector_3.h"
#include "defs.h"
#include "primitives.h"
#include "graphic_text.h"
#include "math_angle.h"
/*--------------------------------------------------------------------------------*/
class GRAPHIC_TEXT_CONTAINER : public GRAPHIC_2D_OBJECT
{

	// -- PUBLIC

public:

	// .. TYPES

    DECLARE_REF( GRAPHIC_TEXT_CONTAINER );
    
    struct DATA
    {
    	TEXT
    		Text;
		MATH_VECTOR_2
			Position,
			ExtentPerChar;
		COLOR
			Color;
		
		DATA() :
			Text()			
		{
			
		}
		// :TODO: Alignement here?
    };

    // .. CONSTRUCTORS

    GRAPHIC_TEXT_CONTAINER() :
    	GRAPHIC_2D_OBJECT(),
    	DataTable(),
    	Font(),
    	ItHasChanged( false )
    {

    }

    virtual ~GRAPHIC_TEXT_CONTAINER()
    {
     
    }

    // .. METHODS

    virtual VOID Update( const TIMER & /*timer*/ )
    {
		if( ItHasChanged )
		{
			GenerateMesh();
		}
    }

    virtual VOID Render()
    {
    	Font->BindTexture();
    	OPENGL_PushMatrix();
    	OPENGL_TranslateXY( Position.X, Position.Y );
    	GRAPHIC_VERTEX_BUFFER::EnableVertexArray( ( REAL * ) VertexTable.GetArray(), 2, sizeof( VERTEX ) );
    	GRAPHIC_VERTEX_BUFFER::EnableTexCoordArray( ( REAL * ) & VertexTable[0].UV , 2, sizeof( VERTEX ) );
    	GRAPHIC_VERTEX_BUFFER::Draw( VertexTable.GetItemCount() );
    	DEBUG_CheckOpenGL();
    	OPENGL_PopMatrix();
    }

    VOID SetFont( const GRAPHIC_FONT::REF & font )
    {
    	Font = font;
    	ItHasChanged = true;
    }
    
    VOID AddText( const TEXT & text, const MATH_VECTOR_2 & position, const MATH_VECTOR_2 & extent_per_char, const COLOR & color = COLOR::ColorWhite )
    {
    	DATA
    		data;
    		
    	data.Text = text;
    	data.Position = position;
    	data.ExtentPerChar = extent_per_char;
    	data.Color = color;
    	
    	DataTable.Add( data );
    	
    	ItHasChanged = true;
    }

    // -- PROTECTED

protected :

	// .. METHODS
	
	VOID AddVertexTableFromData( const INDEX index )
	{
		GRAPHIC_TEXT
			BaseText;
			
		BaseText.SetFont( *Font );
		BaseText.SetExtentPerChar( DataTable[ index ].ExtentPerChar );
		BaseText.SetColor( DataTable[ index ].Color );
		BaseText.SetText( DataTable[ index ].Text );
		BaseText.GenerateMesh( DataTable[ index ].Position );
		
		VertexTable += BaseText.GetVertexTable();
	}
	
	VOID GenerateMesh()
	{
		INDEX
			index;
			
		VertexTable.Clear();
		
		ComputeVisibility();		
			
		for_each_index_in_range( index, VisibleStartIndex, VisibleCount - 1 )
		{
			DEBUG_LogLine( index );
			AddVertexTableFromData( index );
		}
	}
	
	VOID ComputeVisibility()
	{
		if( Extent == MATH_VECTOR_2::Zero )
		{
			VisibleStartIndex = 0;
			VisibleCount = DataTable.GetItemCount();
			return;
		}
	}

    // .. ATTRIBUTES

	ARRAY< DATA >
		DataTable;
    GRAPHIC_FONT::REF
		Font;
	BOOL
		ItHasChanged;
	INDEX
		VisibleStartIndex;
	COUNT
		VisibleCount;
		
    
};
/*--------------------------------------------------------------------------------*/
#endif
